package com.shigen.demo.atguigu;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁代码
 *
 * @author shigenfu
 * @date 2022/5/22 5:14 下午
 */

class MyCache {
  // 保证可见性
  private volatile Map<String, Object> map = new HashMap<>();
  // 保证了原子性，但是不能读
  // private Lock lock = new ReentrantLock();
  private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

  public void put(String key, Object value) {
    readWriteLock.writeLock().lock();
    try {
      System.out.println(Thread.currentThread().getName() + "   写入....");
      TimeUnit.SECONDS.sleep(1);
      map.put(key, value);
      System.out.println(Thread.currentThread().getName() + " finished 写入....");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      readWriteLock.writeLock().unlock();
    }
  }

  public Object get(String key) {
    readWriteLock.readLock().lock();
    try {
      System.out.println(Thread.currentThread().getName() + " 读取.....");
      TimeUnit.SECONDS.sleep(1);
      Object o = map.get(key);
      System.out.println(Thread.currentThread().getName() + " finished 读取.....");
      return o;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      readWriteLock.readLock().unlock();
    }
    return null;
  }

}


public class ReadWriteDemo {

  public static void main(String[] args) {
    MyCache myCache = new MyCache();

    for (int i = 0; i < 5; i++) {
      final int tempInt = i;
      new Thread(() -> {
        myCache.put(tempInt + "", tempInt + "");
      }, String.valueOf(i)).start();
    }

    for (int i = 0; i < 5; i++) {
      final int tempInt = i;
      new Thread(() -> {
        myCache.get(tempInt + "");
      }, String.valueOf(i)).start();
    }
  }

}
